package ldh.im.fxgui;

//import com.github.kwhat.jnativehook.GlobalScreen;
//import com.github.kwhat.jnativehook.NativeHookException;
//import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent;
//import com.github.kwhat.jnativehook.keyboard.NativeKeyListener;
import io.netty.channel.Channel;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import ldh.im.dto.business.ExitReq;
import ldh.im.fxbase.InitDb;
import ldh.im.fxbase.rpc.service.*;
import ldh.im.fxbase.util.*;
import ldh.im.fxgui.rpc.router.*;
import ldh.im.fxbase.service.DefaultFileDownloadAndUploadService;
import ldh.im.fxbase.service.FileDownloadAndUploadService;
import ldh.im.fxgui.rpc.service.ImCommunicateService;
import ldh.im.fxgui.util.UiUtil;
import ldh.im.rpc.LoginFilter;
import ldh.im.rpc.LoginSuccessFilter;
import ldh.im.util.ConfigUtil;
import ldh.rpc.RpcConfig;
import ldh.rpc.cache.LocalRpcCacheService;
import ldh.rpc.client.RpcClientBootstrap;
import ldh.rpc.client.RpcClientSocketBootstrap;
import ldh.rpc.listener.ChannelEventType;
import ldh.rpc.listener.ChannelListener;
import org.slf4j.Logger;

import java.sql.SQLException;

public class MainApp extends TrayApplication { // todo implements NativeKeyListener {

    private static final Logger LOGGER = LoggerUtil.getFileLogger(MainApp.class);

    private RpcClientBootstrap clientBootstrap = null;

    @Override
    public void startPane(Stage primaryStage) {
        Runtime.getRuntime().addShutdownHook(new Thread(()->{
            CloseFactory.getInstance().closeAll();
            ThreadPoolUtil.close();
        }));

        if (StageUtil.isSupportTray()) {
            enableTray(StageUtil.getMainStage());
        }
        primaryStage.initStyle(StageStyle.UNDECORATED);

//        Application.setUserAgentStylesheet(new PrimerDark().getUserAgentStylesheet());
        register();
        // todo
//        GlobalScreen.addNativeKeyListener(this);
        try {
            InitDb initDb = new InitDb();
            initDb.initDb(ConfigUtil.getDataDir());
            initImService();

            new MainUi();
        } catch (SQLException e) {
            LOGGER.error("启动异常", e);
            Stage stage = new Stage();
            Label label = new Label("IM已经开启，不能重复开启");
            Scene scene = new Scene(new StackPane(label), 200, 100);
            stage.setScene(scene);
            stage.show();
            stage.setOnCloseRequest(ee -> {
                LOGGER.info("im exit");
                primaryStage.close();
                CloseFactory.getInstance().closeAll();
                ThreadPoolUtil.close();
                Platform.exit();
//                System.exit(0);
            });
        } catch (Exception e) {
            LOGGER.error("startPane end!!!!!!!!!!!!!!!!!!", e);
            System.exit(0);
        }
    }

    private void initImService() throws Exception {
        clientBootstrap = createClientBootstrap();
        RpcUtil.setRpcBootstrap(clientBootstrap);
        clientBootstrap.addRouters(RpcLoginService.class, RpcPullMessageService.class, RpcMessageService.class, RpcGroupService.class, RpcBaseService.class);

        clientBootstrap.addRouters(MessageConsumerRouter.class, GroupConsumerRouter.class, DataChangeRouter.class, BaseConsumerRouter.class);
        // 语音通信
        clientBootstrap.addRouters(AvConsumerRouter.class, WebRtcConsumerRouter.class, RpcWebRtcService.class);

        clientBootstrap.addFilters(new LoginSuccessFilter(clientBootstrap.getRpcConfig()), new LoginFilter());
        clientBootstrap.start(new ChannelListener() {
            @Override
            public void channelEvent(Channel channel, ChannelEventType channelEventType) {
                if (channelEventType == ChannelEventType.Remove) {
                    FxThreadUtil.runLater(()->{
                        DialogUtil.alert("错误", "连接中断");
                    });
                }
            }
        });

        FileDownloadAndUploadService fileDownloadAndUploadService = new DefaultFileDownloadAndUploadService(clientBootstrap.getRpcConfig().getCacheService());
        RpcUtil.setImService(fileDownloadAndUploadService);
    }

    protected RpcClientBootstrap createClientBootstrap() throws InterruptedException {
        String address = ConfigUtil.getString("socket.address");
        int port = ConfigUtil.getInt("socket.port", 9090);
        RpcConfig rpcConfig = new RpcConfig(new LocalRpcCacheService("client"), address, port, "binary");
        rpcConfig.setBusinessThreadNum(1);
        rpcConfig.setCommunicateService(new ImCommunicateService(rpcConfig));

        RpcClientBootstrap clientBootstrap = new RpcClientSocketBootstrap(rpcConfig);
        return clientBootstrap;
    }

    @Override
    protected void close() {
        if (clientBootstrap != null) {
            logout();
            clientBootstrap.close();
        }
        CloseFactory.getInstance().closeAll();
        ThreadPoolUtil.close();
        super.close();
        System.exit(0);
    }

    private void logout() {
        ThreadPoolUtil.submit(() -> {
            try {
                ExitReq exitReq = new ExitReq();
                exitReq.setExitMessage("logout");
                RpcLoginService rpcLoginService = RpcUtil.getRpcBootstrap().getRpcConfig().getClientBean(RpcLoginService.class);
                rpcLoginService.logout(exitReq);
            } catch (Exception e) {
                LOGGER.error("logout error", e);
            }
        });
        try {
            Thread.sleep(100);
        } catch (Exception e) {
            LOGGER.error("logout sleep error", e);
        }
    }

    private void bindShortKeyCut(Stage primaryStage) {
        // 打开IM
//        KeyCodeCombination openImKey = new KeyCodeCombination(KeyCode.L, KeyCombination.CONTROL_DOWN, KeyCombination.ALT_DOWN);
//        primaryStage.getScene().getAccelerators().put(openImKey, () -> {
//            primaryStage.show();
//            primaryStage.toFront();
//        });

        // 打开截图软件
        KeyCodeCombination openCaptureKey = new KeyCodeCombination(KeyCode.D, KeyCombination.ALT_DOWN);
        primaryStage.getScene().getAccelerators().put(openCaptureKey, () -> {
            UiUtil.getScreenCapturePane().setParentStage(primaryStage);
            UiUtil.getScreenCapturePane().show(imagePath -> {

            }, true);
        });
    }

    // todo
//    public void nativeKeyReleased(NativeKeyEvent nativeEvent) {
//        String ss = nativeEvent.paramString();
//        int mask = NativeKeyEvent.ALT_L_MASK | NativeKeyEvent.CTRL_L_MASK;
//        LOGGER.info("native key release {}, {}, {}, {}", nativeEvent.getRawCode(), nativeEvent.getModifiers(), mask, ss);
//        if (nativeEvent.getModifiers() == mask && nativeEvent.getKeyCode() == NativeKeyEvent.VC_L) {
//            FxThreadUtil.runLater(() -> {
//                StageUtil.getStage().show();
//                StageUtil.getStage().setIconified(false);
//                StageUtil.getStage().toFront();
//            });
//        }
//    }

    private void register() {
        // todo
//        try {
//            GlobalScreen.registerNativeHook();
//        } catch (NativeHookException ex) {
//            LOGGER.error("There was a problem registering the native hook.");
//            LOGGER.error(ex.getMessage());
//        }
    }
}
